package com.sgl.myview.view;

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Scroller;

/**
 * Created by sunqiyong on 2016/12/14.
 */

public class HorizontalWelcomLayout extends ViewGroup{
    //屏幕宽度
    private int mScreenWidth;

    //手指按下时的getScrollX
    private int mScrollStartX;

    private int mScrollEndX;
    //手指按下时的getScrollX

    private int mLastX;

    /**
     * 滚动的辅助类
     */
    private Scroller mScroller;
    /**
     * 是否正在滚动
     */
    private boolean isScrolling;
    /**
     * 加速度检测
     */
    private VelocityTracker mVelocityTracker;
    /**
     * 记录当前页
     */
    private int currentPage = 0;

    private OnPageChangeListener mOnPageChangeListener;


    public HorizontalWelcomLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        /**
         * 获得屏幕的宽度度
         */
        WindowManager mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        mWindowManager.getDefaultDisplay().getMetrics(outMetrics);
        mScreenWidth = outMetrics.widthPixels;

        mScroller = new Scroller(context);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if(changed){
            int childCount = getChildCount();
            //设置主布局的宽度
            MarginLayoutParams mMarginLayoutParams = (MarginLayoutParams) getLayoutParams();
            mMarginLayoutParams.width = mScreenWidth * childCount;
            setLayoutParams(mMarginLayoutParams);

            for(int i = 0;i < childCount;i ++){
                View childView = getChildAt(i);
                if(childView.getVisibility() != View.GONE){
                    childView.layout(i * mScreenWidth,t,(i + 1) * mScreenWidth,b);
                }
            }

        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        for(int i = 0;i < getChildCount(); i++){
            View view = getChildAt(i);
            measureChild(view,mScreenWidth,heightMeasureSpec);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(isScrolling){
            return super.onTouchEvent(event);
        }
        int action = event.getAction();
        int x = (int) event.getX();

        initVeloCity(event);

        switch (action){
            case MotionEvent.ACTION_DOWN:
                mScrollStartX = getScrollX();
                mLastX = x;
                break;
            case MotionEvent.ACTION_MOVE:
                if(!mScroller.isFinished()){
                    mScroller.abortAnimation();
                }
                //确定方向
                int dx = mLastX - x;
                //x轴上一共滑动了多少距离
                int scrollX = getScrollX();
                //dx 小于 0 表示 从左往右 滑动

                /**
                 * 边界值检查
                 * scrollX 表示滑动的总距离，此时由于在最左面，所以这个时候 scrollX 应该是 0 ；
                 * 这个时候继续往右滑动 这个时候 dx 是小于 0 的
                 */
                if(dx < 0 && scrollX + dx < 0){
                    dx = -scrollX;
                }
                /**
                 * 边界值检查
                 * scrollX 表示滑动的总距离,此时由于在最右面，这个时候的 scrollX 应该是空间总宽度（也就是 getChildCount() * mScreenWidth） - mScreenWidth
                 * 这个时候要继续往左滑动，dx 是大于 0 的
                 */
                if(dx > 0 && scrollX + dx > getWidth() - mScreenWidth){
                    dx = getWidth() - mScreenWidth - scrollX;
                }

                scrollBy(dx,0);

                mLastX = x;

                break;
            case MotionEvent.ACTION_UP:
                mScrollEndX = getScrollX();
                int dScrollX = mScrollEndX - mScrollStartX;
                //向右滑动
                if(dScrollX > 0){
                    if(dScrollX > mScreenWidth / 2 ||  Math.abs(getVelocity()) > 600){
                        /**
                         * 表示从点（getScrollX(),0）开始移动，因为点（mScreenWidth - dScrollX,0）的横坐标 大于0 ，所以此处向右移动mScreenWidth - dScrollX距离
                         */
                        mScroller.startScroll(getScrollX(),0,mScreenWidth - dScrollX,0);
                    }else {
                        mScroller.startScroll(getScrollX(),0,- dScrollX,0);
                    }
                }
                //向左滑动
                if(dScrollX < 0){
                    if(mScrollStartX - mScrollEndX > mScreenWidth / 2 || Math.abs(getVelocity()) > 600){
                        mScroller.startScroll(getScrollX(),0,- dScrollX - mScreenWidth,0);
                    }else {
                        mScroller.startScroll(getScrollX(),0,-dScrollX,0);
                    }
                }

                isScrolling = true;
                postInvalidate();
                recycleVelocity();

                break;
        }
        return true;
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {//如果手指离开了屏幕
            scrollTo(mScroller.getCurrX(),0);
            postInvalidate();
        }else {//如果手指还在滑动
            isScrolling = false;
        }
    }

    /**
     * 释放资源
     */
    private void recycleVelocity() {
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }
    }

    /**
     * 获取y方向的加速度
     *
     * @return
     */
    private int getVelocity() {
        mVelocityTracker.computeCurrentVelocity(1000);
        return (int) mVelocityTracker.getXVelocity();
    }


    private void initVeloCity(MotionEvent event){
        if(mVelocityTracker == null){
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);
    }

    /**
     * 设置回调接口
     *
     * @param onPageChangeListener
     */
    public void setOnPageChangeListener(OnPageChangeListener onPageChangeListener) {
        mOnPageChangeListener = onPageChangeListener;
    }

    /**
     * 回调接口
     *
     * @author zhy
     */
    public interface OnPageChangeListener {
        void onPageChange(int currentPage);
    }
}
